1use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10
11use crate::backend::obj::MetaMapType;
12
13pub(crate) fn is_false(v: &bool) -> bool {
16 !v
17}
18
19pub(crate) fn is_zero_f64(v: &f64) -> bool {
20 *v == 0.0
21}
22
23pub(crate) fn is_zero_f32(v: &f32) -> bool {
24 *v == 0.0
25}
26
27pub(crate) fn is_zero_i32(v: &i32) -> bool {
28 *v == 0
29}
30
31#[derive(Debug, Clone, Default, Serialize, Deserialize)]
37pub struct SettingsType {
38 #[serde(rename = "app:*", default, skip_serializing_if = "is_false")]
40 pub app_clear: bool,
41
42 #[serde(rename = "app:globalhotkey", default, skip_serializing_if = "String::is_empty")]
43 pub app_global_hotkey: String,
44
45 #[serde(rename = "app:dismissarchitecturewarning", default, skip_serializing_if = "is_false")]
46 pub app_dismiss_architecture_warning: bool,
47
48 #[serde(rename = "app:defaultnewblock", default, skip_serializing_if = "String::is_empty")]
49 pub app_default_new_block: String,
50
51 #[serde(rename = "app:showoverlayblocknums", default, skip_serializing_if = "Option::is_none")]
52 pub app_show_overlay_block_nums: Option<bool>,
53
54 #[serde(rename = "term:*", default, skip_serializing_if = "is_false")]
56 pub term_clear: bool,
57
58 #[serde(rename = "term:fontsize", default, skip_serializing_if = "is_zero_f64")]
59 pub term_font_size: f64,
60
61 #[serde(rename = "term:fontfamily", default, skip_serializing_if = "String::is_empty")]
62 pub term_font_family: String,
63
64 #[serde(rename = "term:theme", default, skip_serializing_if = "String::is_empty")]
65 pub term_theme: String,
66
67 #[serde(rename = "term:disablewebgl", default, skip_serializing_if = "is_false")]
68 pub term_disable_web_gl: bool,
69
70 #[serde(rename = "term:localshellpath", default, skip_serializing_if = "String::is_empty")]
71 pub term_local_shell_path: String,
72
73 #[serde(rename = "term:localshellopts", default, skip_serializing_if = "Vec::is_empty")]
74 pub term_local_shell_opts: Vec<String>,
75
76 #[serde(rename = "term:scrollback", default, skip_serializing_if = "Option::is_none")]
77 pub term_scrollback: Option<i64>,
78
79 #[serde(rename = "term:copyonselect", default, skip_serializing_if = "Option::is_none")]
80 pub term_copy_on_select: Option<bool>,
81
82 #[serde(rename = "term:transparency", default, skip_serializing_if = "Option::is_none")]
83 pub term_transparency: Option<f64>,
84
85 #[serde(rename = "term:allowbracketedpaste", default, skip_serializing_if = "Option::is_none")]
86 pub term_allow_bracketed_paste: Option<bool>,
87
88 #[serde(rename = "term:shiftenternewline", default, skip_serializing_if = "Option::is_none")]
89 pub term_shift_enter_newline: Option<bool>,
90
91 #[serde(rename = "term:agentmaxruntimehours", default, skip_serializing_if = "is_zero_f64")]
94 pub term_agent_max_runtime_hours: f64,
95
96 #[serde(rename = "term:agentidletimeoutmins", default, skip_serializing_if = "is_zero_f64")]
99 pub term_agent_idle_timeout_mins: f64,
100
101 #[serde(rename = "cmd:env", default, skip_serializing_if = "HashMap::is_empty")]
103 pub cmd_env: HashMap<String, String>,
104
105 #[serde(rename = "blockheader:*", default, skip_serializing_if = "is_false")]
107 pub block_header_clear: bool,
108
109 #[serde(rename = "blockheader:showblockids", default, skip_serializing_if = "is_false")]
110 pub block_header_show_block_ids: bool,
111
112 #[serde(rename = "preview:showhiddenfiles", default, skip_serializing_if = "Option::is_none")]
114 pub preview_show_hidden_files: Option<bool>,
115
116 #[serde(rename = "tab:preset", default, skip_serializing_if = "String::is_empty")]
118 pub tab_preset: String,
119
120 #[serde(rename = "widget:*", default, skip_serializing_if = "is_false")]
122 pub widget_clear: bool,
123
124 #[serde(rename = "widget:showhelp", default, skip_serializing_if = "Option::is_none")]
125 pub widget_show_help: Option<bool>,
126
127 #[serde(rename = "widget:icononly", default, skip_serializing_if = "Option::is_none")]
128 pub widget_icon_only: Option<bool>,
129
130 #[serde(rename = "window:*", default, skip_serializing_if = "is_false")]
132 pub window_clear: bool,
133
134 #[serde(rename = "window:transparent", default, skip_serializing_if = "is_false")]
135 pub window_transparent: bool,
136
137 #[serde(rename = "window:blur", default, skip_serializing_if = "is_false")]
138 pub window_blur: bool,
139
140 #[serde(rename = "window:opacity", default, skip_serializing_if = "Option::is_none")]
141 pub window_opacity: Option<f64>,
142
143 #[serde(rename = "window:bgcolor", default, skip_serializing_if = "String::is_empty")]
144 pub window_bg_color: String,
145
146 #[serde(rename = "window:reducedmotion", default, skip_serializing_if = "is_false")]
147 pub window_reduced_motion: bool,
148
149 #[serde(rename = "window:tilegapsize", default, skip_serializing_if = "Option::is_none")]
150 pub window_tile_gap_size: Option<i64>,
151
152 #[serde(rename = "window:showmenubar", default, skip_serializing_if = "is_false")]
153 pub window_show_menu_bar: bool,
154
155 #[serde(rename = "window:nativetitlebar", default, skip_serializing_if = "is_false")]
156 pub window_native_title_bar: bool,
157
158 #[serde(rename = "window:disablehardwareacceleration", default, skip_serializing_if = "is_false")]
159 pub window_disable_hardware_acceleration: bool,
160
161 #[serde(rename = "window:maxtabcachesize", default, skip_serializing_if = "is_zero_i32")]
162 pub window_max_tab_cache_size: i32,
163
164 #[serde(rename = "window:magnifiedblockopacity", default, skip_serializing_if = "Option::is_none")]
165 pub window_magnified_block_opacity: Option<f64>,
166
167 #[serde(rename = "window:magnifiedblocksize", default, skip_serializing_if = "Option::is_none")]
168 pub window_magnified_block_size: Option<f64>,
169
170 #[serde(rename = "window:magnifiedblockblurprimarypx", default, skip_serializing_if = "Option::is_none")]
171 pub window_magnified_block_blur_primary_px: Option<i64>,
172
173 #[serde(rename = "window:magnifiedblockblursecondarypx", default, skip_serializing_if = "Option::is_none")]
174 pub window_magnified_block_blur_secondary_px: Option<i64>,
175
176 #[serde(rename = "window:confirmclose", default, skip_serializing_if = "is_false")]
177 pub window_confirm_close: bool,
178
179 #[serde(rename = "window:savelastwindow", default, skip_serializing_if = "is_false")]
180 pub window_save_last_window: bool,
181
182 #[serde(rename = "window:dimensions", default, skip_serializing_if = "String::is_empty")]
183 pub window_dimensions: String,
184
185 #[serde(rename = "window:zoom", default, skip_serializing_if = "Option::is_none")]
186 pub window_zoom: Option<f64>,
187
188 #[serde(rename = "telemetry:*", default, skip_serializing_if = "is_false")]
190 pub telemetry_clear: bool,
191
192 #[serde(rename = "telemetry:enabled", default, skip_serializing_if = "is_false")]
193 pub telemetry_enabled: bool,
194
195 #[serde(rename = "telemetry:interval", default, skip_serializing_if = "is_zero_f64")]
196 pub telemetry_interval: f64,
197
198 #[serde(rename = "telemetry:numpoints", default, skip_serializing_if = "Option::is_none")]
199 pub telemetry_numpoints: Option<i64>,
200
201 #[serde(rename = "conn:*", default, skip_serializing_if = "is_false")]
203 pub conn_clear: bool,
204
205 #[serde(rename = "network:lan_discovery", default, skip_serializing_if = "is_false")]
207 pub network_lan_discovery: bool,
208
209 #[serde(rename = "voice:enabled", default, skip_serializing_if = "Option::is_none")]
219 pub voice_enabled: Option<bool>,
220
221 #[serde(flatten, default, skip_serializing_if = "HashMap::is_empty")]
224 pub extra: HashMap<String, serde_json::Value>,
225}
226
227#[derive(Debug, Clone, Default, Serialize, Deserialize)]
231pub struct MimeTypeConfigType {
232 #[serde(default, skip_serializing_if = "String::is_empty")]
233 pub icon: String,
234
235 #[serde(default, skip_serializing_if = "String::is_empty")]
236 pub color: String,
237}
238
239#[derive(Debug, Clone, Default, Serialize, Deserialize)]
241pub struct FileDef {
242 #[serde(default, skip_serializing_if = "String::is_empty")]
243 pub content: String,
244
245 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
246 pub meta: HashMap<String, Value>,
247}
248
249#[derive(Debug, Clone, Default, Serialize, Deserialize)]
251pub struct BlockDef {
252 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
253 pub files: HashMap<String, FileDef>,
254
255 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
256 pub meta: MetaMapType,
257}
258
259#[derive(Debug, Clone, Default, Serialize, Deserialize)]
261pub struct WidgetConfigType {
262 #[serde(rename = "display:order", default, skip_serializing_if = "is_zero_f64")]
263 pub display_order: f64,
264
265 #[serde(rename = "display:hidden", default, skip_serializing_if = "is_false")]
266 pub display_hidden: bool,
267
268 #[serde(rename = "display:pinned", default, skip_serializing_if = "is_false")]
271 pub display_pinned: bool,
272
273 #[serde(default, skip_serializing_if = "String::is_empty")]
274 pub icon: String,
275
276 #[serde(default, skip_serializing_if = "String::is_empty")]
277 pub color: String,
278
279 #[serde(default, skip_serializing_if = "String::is_empty")]
280 pub label: String,
281
282 #[serde(default, skip_serializing_if = "String::is_empty")]
283 pub description: String,
284
285 #[serde(default, skip_serializing_if = "is_false")]
286 pub magnified: bool,
287
288 #[serde(rename = "blockdef", default)]
289 pub block_def: BlockDef,
290}
291
292#[derive(Debug, Clone, Default, Serialize, Deserialize)]
294pub struct TermThemeType {
295 #[serde(rename = "display:name", default, skip_serializing_if = "String::is_empty")]
296 pub display_name: String,
297
298 #[serde(rename = "display:order", default, skip_serializing_if = "is_zero_f64")]
299 pub display_order: f64,
300
301 #[serde(default, skip_serializing_if = "String::is_empty")]
302 pub black: String,
303 #[serde(default, skip_serializing_if = "String::is_empty")]
304 pub red: String,
305 #[serde(default, skip_serializing_if = "String::is_empty")]
306 pub green: String,
307 #[serde(default, skip_serializing_if = "String::is_empty")]
308 pub yellow: String,
309 #[serde(default, skip_serializing_if = "String::is_empty")]
310 pub blue: String,
311 #[serde(default, skip_serializing_if = "String::is_empty")]
312 pub magenta: String,
313 #[serde(default, skip_serializing_if = "String::is_empty")]
314 pub cyan: String,
315 #[serde(default, skip_serializing_if = "String::is_empty")]
316 pub white: String,
317
318 #[serde(rename = "brightBlack", default, skip_serializing_if = "String::is_empty")]
319 pub bright_black: String,
320 #[serde(rename = "brightRed", default, skip_serializing_if = "String::is_empty")]
321 pub bright_red: String,
322 #[serde(rename = "brightGreen", default, skip_serializing_if = "String::is_empty")]
323 pub bright_green: String,
324 #[serde(rename = "brightYellow", default, skip_serializing_if = "String::is_empty")]
325 pub bright_yellow: String,
326 #[serde(rename = "brightBlue", default, skip_serializing_if = "String::is_empty")]
327 pub bright_blue: String,
328 #[serde(rename = "brightMagenta", default, skip_serializing_if = "String::is_empty")]
329 pub bright_magenta: String,
330 #[serde(rename = "brightCyan", default, skip_serializing_if = "String::is_empty")]
331 pub bright_cyan: String,
332 #[serde(rename = "brightWhite", default, skip_serializing_if = "String::is_empty")]
333 pub bright_white: String,
334
335 #[serde(default, skip_serializing_if = "String::is_empty")]
336 pub gray: String,
337 #[serde(rename = "cmdtext", default, skip_serializing_if = "String::is_empty")]
338 pub cmd_text: String,
339 #[serde(default, skip_serializing_if = "String::is_empty")]
340 pub foreground: String,
341 #[serde(rename = "selectionBackground", default, skip_serializing_if = "String::is_empty")]
342 pub selection_background: String,
343 #[serde(default, skip_serializing_if = "String::is_empty")]
344 pub background: String,
345 #[serde(default, skip_serializing_if = "String::is_empty")]
346 pub cursor: String,
347}
348
349#[derive(Debug, Clone, Default, Serialize, Deserialize)]
351pub struct WebBookmark {
352 #[serde(default)]
353 pub url: String,
354
355 #[serde(default, skip_serializing_if = "String::is_empty")]
356 pub title: String,
357
358 #[serde(default, skip_serializing_if = "String::is_empty")]
359 pub icon: String,
360
361 #[serde(rename = "iconcolor", default, skip_serializing_if = "String::is_empty")]
362 pub icon_color: String,
363
364 #[serde(rename = "iconurl", default, skip_serializing_if = "String::is_empty")]
365 pub icon_url: String,
366
367 #[serde(rename = "display:order", default, skip_serializing_if = "is_zero_f64")]
368 pub display_order: f64,
369}
370
371#[derive(Debug, Clone, Default, Serialize, Deserialize)]
374pub struct ConnKeywords {
375 #[serde(rename = "conn:shellpath", default, skip_serializing_if = "String::is_empty")]
377 pub conn_shell_path: String,
378
379 #[serde(rename = "conn:ignoresshconfig", default, skip_serializing_if = "Option::is_none")]
380 pub conn_ignore_ssh_config: Option<bool>,
381
382 #[serde(rename = "display:hidden", default, skip_serializing_if = "Option::is_none")]
384 pub display_hidden: Option<bool>,
385
386 #[serde(rename = "display:order", default, skip_serializing_if = "is_zero_f32")]
387 pub display_order: f32,
388
389 #[serde(rename = "term:*", default, skip_serializing_if = "is_false")]
391 pub term_clear: bool,
392
393 #[serde(rename = "term:fontsize", default, skip_serializing_if = "is_zero_f64")]
394 pub term_font_size: f64,
395
396 #[serde(rename = "term:fontfamily", default, skip_serializing_if = "String::is_empty")]
397 pub term_font_family: String,
398
399 #[serde(rename = "term:theme", default, skip_serializing_if = "String::is_empty")]
400 pub term_theme: String,
401
402 #[serde(rename = "cmd:env", default, skip_serializing_if = "HashMap::is_empty")]
404 pub cmd_env: HashMap<String, String>,
405
406 #[serde(rename = "cmd:initscript", default, skip_serializing_if = "String::is_empty")]
407 pub cmd_init_script: String,
408
409 #[serde(rename = "cmd:initscript.sh", default, skip_serializing_if = "String::is_empty")]
410 pub cmd_init_script_sh: String,
411
412 #[serde(rename = "cmd:initscript.bash", default, skip_serializing_if = "String::is_empty")]
413 pub cmd_init_script_bash: String,
414
415 #[serde(rename = "cmd:initscript.zsh", default, skip_serializing_if = "String::is_empty")]
416 pub cmd_init_script_zsh: String,
417
418 #[serde(rename = "cmd:initscript.pwsh", default, skip_serializing_if = "String::is_empty")]
419 pub cmd_init_script_pwsh: String,
420
421 #[serde(rename = "cmd:initscript.fish", default, skip_serializing_if = "String::is_empty")]
422 pub cmd_init_script_fish: String,
423
424 #[serde(rename = "ssh:user", default, skip_serializing_if = "Option::is_none")]
426 pub ssh_user: Option<String>,
427
428 #[serde(rename = "ssh:hostname", default, skip_serializing_if = "Option::is_none")]
429 pub ssh_hostname: Option<String>,
430
431 #[serde(rename = "ssh:port", default, skip_serializing_if = "Option::is_none")]
432 pub ssh_port: Option<String>,
433
434 #[serde(rename = "ssh:identityfile", default, skip_serializing_if = "Vec::is_empty")]
435 pub ssh_identity_file: Vec<String>,
436
437 #[serde(rename = "ssh:batchmode", default, skip_serializing_if = "Option::is_none")]
438 pub ssh_batch_mode: Option<bool>,
439
440 #[serde(rename = "ssh:pubkeyauthentication", default, skip_serializing_if = "Option::is_none")]
441 pub ssh_pubkey_authentication: Option<bool>,
442
443 #[serde(rename = "ssh:passwordauthentication", default, skip_serializing_if = "Option::is_none")]
444 pub ssh_password_authentication: Option<bool>,
445
446 #[serde(rename = "ssh:kbdinteractiveauthentication", default, skip_serializing_if = "Option::is_none")]
447 pub ssh_kbd_interactive_authentication: Option<bool>,
448
449 #[serde(rename = "ssh:preferredauthentications", default, skip_serializing_if = "Vec::is_empty")]
450 pub ssh_preferred_authentications: Vec<String>,
451
452 #[serde(rename = "ssh:addkeystoagent", default, skip_serializing_if = "Option::is_none")]
453 pub ssh_add_keys_to_agent: Option<bool>,
454
455 #[serde(rename = "ssh:identityagent", default, skip_serializing_if = "Option::is_none")]
456 pub ssh_identity_agent: Option<String>,
457
458 #[serde(rename = "ssh:identitiesonly", default, skip_serializing_if = "Option::is_none")]
459 pub ssh_identities_only: Option<bool>,
460
461 #[serde(rename = "ssh:proxyjump", default, skip_serializing_if = "Vec::is_empty")]
462 pub ssh_proxy_jump: Vec<String>,
463
464 #[serde(rename = "ssh:userknownhostsfile", default, skip_serializing_if = "Vec::is_empty")]
465 pub ssh_user_known_hosts_file: Vec<String>,
466
467 #[serde(rename = "ssh:globalknownhostsfile", default, skip_serializing_if = "Vec::is_empty")]
468 pub ssh_global_known_hosts_file: Vec<String>,
469}
470
471#[derive(Debug, Clone, Default, Serialize, Deserialize)]
473pub struct ConfigError {
474 pub file: String,
475 pub err: String,
476}
477
478#[allow(dead_code)]
480#[derive(Debug, Clone, Default, Serialize, Deserialize)]
481pub struct WebhookConfigType {
482 #[serde(default)]
483 pub version: String,
484
485 #[serde(rename = "workspaceId", default)]
486 pub workspace_id: String,
487
488 #[serde(rename = "authToken", default)]
489 pub auth_token: String,
490
491 #[serde(rename = "cloudEndpoint", default)]
492 pub cloud_endpoint: String,
493
494 #[serde(default)]
495 pub enabled: bool,
496
497 #[serde(default)]
498 pub terminals: Vec<String>,
499}
500
501#[derive(Debug, Clone, Default, Serialize, Deserialize)]
506pub struct FullConfigType {
507 #[serde(default)]
508 pub settings: SettingsType,
509
510 #[serde(rename = "mimetypes", default)]
511 pub mime_types: HashMap<String, MimeTypeConfigType>,
512
513 #[serde(rename = "defaultwidgets", default)]
514 pub default_widgets: HashMap<String, WidgetConfigType>,
515
516 #[serde(default)]
517 pub widgets: HashMap<String, WidgetConfigType>,
518
519 #[serde(default)]
520 pub presets: HashMap<String, MetaMapType>,
521
522 #[serde(rename = "termthemes", default)]
523 pub term_themes: HashMap<String, TermThemeType>,
524
525 #[serde(default)]
526 pub connections: HashMap<String, ConnKeywords>,
527
528 #[serde(default)]
529 pub bookmarks: HashMap<String, WebBookmark>,
530
531 #[serde(rename = "configerrors", default, skip_serializing_if = "Vec::is_empty")]
532 pub config_errors: Vec<ConfigError>,
533}